"""
Simple Snow
Based primarily on:
https://api.arcade.academy/en/latest/examples/sprite_collect_coins_move_down.html

Contributed to Python Arcade Library by Nicholas Hartunian

If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.snow
"""

import random
import math
import arcade

WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720
WINDOW_TITLE = "Snow"
SNOWFLAKE_COUNT = 800


class Snowflake(arcade.SpriteCircle):
    """
    Each instance of this class represents a single snowflake.
    Based on drawing filled-circles.
    每个实例代表一片雪花，基于填充圆模拟
    """

    def __init__(self, size, speed, drift):
        super().__init__(size, arcade.color.WHITE)
        # speed是雪花的下落速度，drift是偏移弧度
        self.speed = speed
        self.drift = drift

    def reset_pos(self):
        # Reset flake to random position above screen
        # 重置位置（x坐标随机，y坐标随机在顶部到以下100像素的位置）
        # 注：此处的position应是精灵的固有属性
        self.position = (
            random.randrange(WINDOW_WIDTH),
            random.randrange(WINDOW_HEIGHT, WINDOW_HEIGHT + 100),
        )

    def update(self, delta_time: float = 1/60) -> None:
        # 根据设置速度，稳定变更雪花y坐标
        self.center_y -= self.speed * delta_time

        # Check if snowflake has fallen below screen
        # 如果雪花调到窗口外，则重置坐标
        if self.center_y < 0:
            self.reset_pos()

        # Some math to make the snowflakes move side to side
        # 此处x坐标变更值，并不是从负无穷到正无穷，而是distance_y的正负区间内摇摆
        self.center_x += self.speed * math.cos(self.drift) * delta_time
        # 偏移弧度，所有雪花均周期性变化（且是一样的周期）
        self.drift += 1 * delta_time


class GameView(arcade.View):
    """ Main application class. """

    def __init__(self):
        """ Initializer """
        # Calls "__init__" of parent class (arcade.Window) to setup screen
        super().__init__()

        # 初始化雪花精灵
        self.snowflake_list = arcade.SpriteList()

        # Don't show the mouse pointer
        self.window.set_mouse_visible(False)

        # Set the background color
        self.background_color = arcade.color.BLACK

    def start_snowfall(self):
        """ Set up snowfall and initialize variables. """
        # 默认创建800个雪花
        for i in range(SNOWFLAKE_COUNT):
            # Create snowflake instance
            # 雪花大小，从1px到4px之间
            # 下落速度是20px~40px之间（每秒）
            # 摇摆弧度，则是相当于全随机
            snowflake = Snowflake(
                size=random.randrange(1, 4),
                speed=random.randrange(20, 40),
                drift=random.uniform(math.pi, math.pi * 2),
            )
            # Randomly position snowflake
            # 雪花初始位置（x坐标随机，y坐标则从0到顶部+200px的位置）
            snowflake.position = (
                random.randrange(WINDOW_WIDTH),
                random.randrange(WINDOW_HEIGHT + 200),
            )
            # Add snowflake to snowflake list
            # 添加雪花精灵
            self.snowflake_list.append(snowflake)

    def on_draw(self):
        """ Render the screen. """
        # Clear the screen to the background color
        self.clear()

        # Draw the current position of each snowflake
        # 雪花精灵批量绘画
        self.snowflake_list.draw()

    def on_update(self, delta_time):
        """ All the logic to move, and the game logic goes here. """
        # Call update on all the snowflakes
        # 雪花精灵批量更新
        self.snowflake_list.update(delta_time)


def main():
    """ Main function """
    # Create a window class. This is what actually shows up on screen
    # 初始化窗口
    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)

    # Create and setup the GameView
    # 初始化view
    game = GameView()
    # 初始化雪花精灵
    game.start_snowfall()

    # Show GameView on screen
    # window展示view
    window.show_view(game)

    # Start the arcade game loop
    # 开始运行
    arcade.run()


if __name__ == "__main__":
    main()